package com.icloud.article.boot.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icloud.article.boot.dao.RewardDao;
import com.icloud.article.boot.dto.RewardDto;
import com.icloud.common.core.api.CommonResult;
import com.icloud.common.core.api.ResultCode;
import com.icloud.common.database.mapper.ArticleMapper;
import com.icloud.common.database.mapper.TOrderMapper;
import com.icloud.common.database.mapper.TRewardOrderItemMapper;
import com.icloud.common.database.model.Article;
import com.icloud.common.database.model.TOrders;
import com.icloud.common.database.model.TRewardOrderItem;
import com.icloud.article.boot.service.RewardService;
import com.icloud.common.web.exception.ApiException;
import com.icloud.common.web.exception.Asserts;
import com.icloud.common.web.util.AuthUtil;
import com.icloud.wallet.api.dto.CustomerRewardDto;
import com.icloud.wallet.api.feign.CustomerOrderFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 打赏service 实现类
 */

@Service
public class RewardServiceImpl extends ServiceImpl<TRewardOrderItemMapper, TRewardOrderItem> implements RewardService {
    @Autowired
    private RewardDao rewardDao;
    @Autowired
    private TOrderMapper tOrderMapper;
    @Autowired
    private TRewardOrderItemMapper tRewardOrderItemMapper;
    @Autowired
    private AuthUtil authUtil;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private CustomerOrderFeign customerOrderFeign;

    /**
     * 打赏
     * @param dto
     */
    @Override
    public boolean reward(RewardDto dto) {
        Long customerId = dto.getCustomerId();
        if(customerId!=null){
            Asserts.fail(!customerId.equals(authUtil.getUserId()), ResultCode.VALIDATE_FAILED);
        }else{
            customerId=authUtil.getUserId();
        }
        Long articleId = dto.getArticleId();
        Article article = articleMapper.selectById(articleId);
        Asserts.fail(null==article, ResultCode.DATA_NOT_EXISTS);

        BigDecimal amount = dto.getAmount();
        if(amount.compareTo(BigDecimal.ZERO)<=0){
            log.warn("打赏金额应大于0");
            Asserts.fail(!customerId.equals(authUtil.getUserId()), ResultCode.VALIDATE_FAILED);
        }
        Long authorId = article.getCreatedId();
        Asserts.fail(authorId.equals(customerId), ResultCode.VALIDATE_FAILED);

        CustomerRewardDto customerRewardDto = new CustomerRewardDto();
        customerRewardDto.setCreatedId(customerId);
        customerRewardDto.setArticleId(articleId);
        customerRewardDto.setAuthorId(authorId);
        customerRewardDto.setRewardTime(dto.getRewardTime());
        customerRewardDto.setAmount(dto.getAmount());

        CommonResult<Boolean> commonResult = customerOrderFeign.rewardArticle(customerRewardDto);
        if(commonResult.getCode()!=ResultCode.SUCCESS.getCode()){
            ResultCode resultCode = ResultCode.byCode(commonResult.getCode());
            if(resultCode==null){
                throw new ApiException(ResultCode.SYSTEM_ERROR);
            }else {
                throw new ApiException(resultCode);
            }
        }

        return true;
    }

    /**
     * 根据帖子id查询打赏金额
     * @param articleIds    帖子id
     * @return
     */
    @Override
    public Map<Long, BigDecimal> queryRewardAmountByArticle(List<Long> articleIds) {
        Map<Long, BigDecimal> rewardMap = new HashMap<>();
        LambdaQueryWrapper<TRewardOrderItem> rewardItemQuery = new LambdaQueryWrapper<>();
        rewardItemQuery.in(TRewardOrderItem::getArticleId, articleIds);
        List<TRewardOrderItem> rewardOrderItemList = tRewardOrderItemMapper.selectList(rewardItemQuery);
        if(CollectionUtil.isEmpty(rewardOrderItemList)){
            return rewardMap;
        }
        Map<Long, TRewardOrderItem> itemMap = rewardOrderItemList.stream().collect(Collectors.toMap(TRewardOrderItem::getOrderId, Function.identity()));
        List<Long> orderIdList = rewardOrderItemList.stream().map(TRewardOrderItem::getOrderId).collect(Collectors.toList());
        List<TOrders> orderList = tOrderMapper.selectBatchIds(orderIdList);
        Map<Long, TOrders> orderMap = orderList.stream().collect(Collectors.toMap(TOrders::getId, Function.identity()));

        orderMap.forEach((k,v)->{
            TRewardOrderItem item = itemMap.get(k);
            if(item!=null){
                Long articleId = item.getArticleId();
                BigDecimal amount = v.getAmount();
                BigDecimal bal = rewardMap.get(articleId);
                if(bal==null){
                    bal = BigDecimal.ZERO;
                }
                bal = bal.add(amount);
                rewardMap.put(articleId, bal);
            }
        });
        return rewardMap;
    }
}
